package vip.caressing.service.impl;

import vip.caressing.service.List;

import java.util.function.Consumer;

/**
 * @ Author:     15744
 * @ Date:       2024/1/30 15:27
 * @ Created by  15744
 * @ Description:
 * @author 15744
 */
public class ArrayList<E> implements List<E> {
    
    private E[] array;
    
    // 数组大小
    private int size;
    
    // 初始化长度
    private static final int INIT_LENGTH = 16;
    
    // 使用构造器创建数组的时候，将array初始化
    public ArrayList() {
        array = (E[]) new Object[INIT_LENGTH];
    }
    
    @Override
    public int size() {
        return this.size;
    }
    
    @Override
    public boolean isEmpty() {
        return size == 0;
    }
    
    @Override
    public void add(E element) {
        add(size, element);
    }
    
    @Override
    public void add(int index, E element) {
        // index = size 表示在组尾增加元素，否则表示在组中间加入
        if (index > size || index < 0){
            System.out.println("角标越界");
        }
        
        // 目标位置后面的所有项 向后移一位。index=size的位置表示比原来数组多出的一位，所以从这里开始放置以前的数据
        for (int i = size; i > index; i--){
            array[i] = array[i-1];
        }
        
        // 赋值
        array[index] = element;
        
        // 数组新增元素，长度加一
        size++;
        
        // 判断是否需要扩容，这里使用array.legnth因为INIT_LENGTH是final值
        if (size == array.length){
            grow(); // 调用扩容函数，降低耦合
        }
    }
    
    private void grow(){
        // 扩容到原来的2倍
        E[] newArray = (E[]) new Object[array.length * 2];
        
        // 将原数组的元素复制到新数组
        System.arraycopy(array, 0, newArray, 0, array.length);
        
        // 将新数组赋值给原数组
        array = newArray;
    }
    
    
    @Override
    public E get(int index) {
        if (index >= 0 && index < size){
            return array[index];
        }
        return null;
    }
    
    @Override
    public E remove(int index) {
        if (index >= 0 && index < size){
            E result = array[index];
            for (int i = index; i < size; i++) {
                // 这里是否有问题，size=array.length且i=size+1时，array[i+1]越界吧
                // 经验证，在数组长度达到array.length的时候会扩容，所以不会出现角标越界
                array[i] = array[i+1];
            }
            array[size-1] = null;
            size--;
            return result;
        }
        return null;
    }
    
    @Override
    public E set(int index, E element) {
        if (index >= 0 && index < size){
            E result = array[index];
            array[index] = element;
            return result;
        }
        return null;
    }
    
    @Override
    public void forEach(Consumer<E> consumer) {
        for (int i = 0; i < size; i++) {
            // accept方法用于指定泛型，而形参consumer表示具体的函数[即如何消费accept方法接收的参数]
            consumer.accept(array[i]);
//            consumer.accept(array[0]);    // 用这个试试能否遍历
        }
    }
    
    @Override
    public String toString() {
        //1数组为空
        if(isEmpty()){
            return "[]";
        }
        //2创建对象
        StringBuilder builder = new StringBuilder();
        //3遍历数组，拼写结果
        builder.append("[");
        forEach(element->builder.append(element).append(","));
        builder.replace(builder.length()-1,builder.length(),"]");
        return builder.toString();
    }
}
